package com.renjianbo.project;

import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.converts.MySqlTypeConvert;
import com.baomidou.mybatisplus.generator.config.po.TableFill;
import com.baomidou.mybatisplus.generator.config.querys.MySqlQuery;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.DbColumnType;
import com.baomidou.mybatisplus.generator.config.rules.IColumnType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import com.renjianbo.project.common.util.CodeGeneratorUtil;

import java.io.File;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author 任建波
 * @date 2019/9/6 16:41
 */
public class CodeGenerator {

    /**
     * 生成器
     * @param author    作者
     * @param tableName   表名
     * @param moduleName 模块名
     * @param packagePath   包名
     */
    public static void generator(String author, String tableName, String moduleName, String packagePath) {
        String projectPath = System.getProperty("user.dir");
        String srcPath = projectPath + "\\src\\main\\java\\";
        String resourcesPath = projectPath + "\\src\\main\\resources\\";
        String projectPackagePath = packagePath + ".module." + moduleName;
        String database = "authentication";

        // 全局配置
        GlobalConfig globalConfig = new GlobalConfig();
        globalConfig.setOutputDir(srcPath);
        globalConfig.setAuthor(author);  //  作者
        globalConfig.setEnableCache(false);// XML 二级缓存
        globalConfig.setOpen(false);    // 是否打开输出目录 默认true
        globalConfig.setFileOverride(false); // 是否覆盖文件
        globalConfig.setBaseColumnList(false); // 基本的sql片段
        globalConfig.setBaseResultMap(false); // 基本的字段映射
        //         globalConfig.setEntityName("%sEntity");			//实体命名方式  默认值：null 例如：%sEntity 生成 UserEntity
//        globalConfig.setMapperName("%sDao");    //  dao层
//        globalConfig.setXmlName("%sMapper");    //Mapper xml 命名方式   默认值：null 例如：%sDao 生成 UserDao.xml
        globalConfig.setServiceName("%sService");   //service 命名方式   默认值：null 例如：%sBusiness 生成 UserBusiness
//         globalConfig.setServiceImplName("%sServiceImpl");	//service impl 命名方式  默认值：null 例如：%sBusinessImpl 生成 UserBusinessImpl
//         globalConfig.setControllerName("%sController");	//controller 命名方式    默认值：null 例如：%sAction 生成 UserAction
        globalConfig.setDateType(DateType.ONLY_DATE);  //定义实体类中日期类型
        globalConfig.setSwagger2(true);    //   开启swagger2模式

        // 数据源配置
        DataSourceConfig dataSource = new DataSourceConfig();
        dataSource.setUrl("jdbc:mysql://bj-cdb-i1br6l1c.sql.tencentcdb.com:60110/" + database + "?useUnicode=true&characterEncoding=utf8&autoReconnect=true&useSSL=false&serverTimezone=Asia/Shanghai");
        dataSource.setDriverName("com.mysql.cj.jdbc.Driver");
        dataSource.setUsername("root");
        dataSource.setPassword("a8990521125");
        dataSource.setTypeConvert(new MySqlTypeConvert(){
            // 自定义数据库表字段类型转换【可选】
            @Override
            public IColumnType processTypeConvert(GlobalConfig globalConfig, String fieldType) {
                if ( fieldType.toLowerCase().contains( "datetime" ) ) {
                    return DbColumnType.DATE;
                }
                if ( fieldType.toLowerCase().contains( "tinyint" ) ) {
                    return DbColumnType.SHORT;
                }
                return super.processTypeConvert(globalConfig, fieldType);
            }
        });
        dataSource.setDbQuery(new MySqlQuery() {
            @Override
            public String tableFieldsSql() {
                return " show full fields from `%s` ";
//                return " SELECT Column_Name FIELD, column_type Type, collation_name COLLATION, is_nullable 'Null', column_key 'Key', column_default 'Default', extra, PRIVILEGES, column_comment COMMENT, NUMERIC_PRECISION,  NUMERIC_SCALE, CHARACTER_MAXIMUM_LENGTH FROM information_schema.COLUMNS WHERE table_schema = '" + database + "' AND table_name = `%s`; ";
            }

            /**
             * mysql属性查询：SHow full fields from sys_permission
             * 重写父类预留查询自定义字段
             * 这里查询的 SQL 对应父类 tableFieldsSql 的查询字段，默认不能满足你的需求请重写它
             * 模板中调用：  table.fields 获取所有字段信息，
             * 然后循环字段获取 field.customMap 从 MAP 中获取注入字段如下  Null
             */
            @Override
            public String[] fieldCustom() {
                return new String[]{ "Null" };
            }
        });

        // 包配置
        PackageConfig packageConfig = new PackageConfig();
        packageConfig.setParent(packagePath + ".module");    //  包名
        packageConfig.setModuleName(moduleName);
//        packageConfig.setController("controller." + moduleName);
        packageConfig.setEntity("model." + tableName.toLowerCase());
//        packageConfig.setXml("/mapper/" + moduleName); //  Mapper.xml文件位置
//        packageConfig.setService("service." + moduleName);
//        packageConfig.setServiceImpl("service." + moduleName +".impl");
//        packageConfig.setMapper("dao." + moduleName);
        Map<String, String> pathInfo = new HashMap<>();
        pathInfo.put(ConstVal.CONTROLLER_PATH, srcPath + (projectPackagePath + ".controller").replaceAll("\\.", StringPool.BACK_SLASH + File.separator));
        pathInfo.put(ConstVal.SERVICE_PATH, srcPath + (projectPackagePath + ".service").replaceAll("\\.", StringPool.BACK_SLASH + File.separator));
        pathInfo.put(ConstVal.SERVICE_IMPL_PATH, srcPath + (projectPackagePath + ".service.impl").replaceAll("\\.", StringPool.BACK_SLASH + File.separator));
        pathInfo.put(ConstVal.ENTITY_PATH, srcPath + (projectPackagePath + ".model." + tableName.toLowerCase()).replaceAll("\\.", StringPool.BACK_SLASH + File.separator));
        pathInfo.put(ConstVal.MAPPER_PATH, srcPath + (projectPackagePath + ".mapper").replaceAll("\\.", StringPool.BACK_SLASH + File.separator));
        pathInfo.put(ConstVal.XML_PATH, resourcesPath + "mapper\\" + moduleName + "\\");
        packageConfig.setPathInfo(pathInfo);

        // 自定义配置
        InjectionConfig cfg = new InjectionConfig() {
            @Override
            public void initMap() {
                //  该对象可以传递到模板引擎通过 cfg.xxx 引用
                Map<String, Object> map = new HashMap<>();
                map.put("packagePath", packagePath);
                this.setMap(map);
            }
        };

        // 自定义配置会被优先输出
        List<FileOutConfig> fileOutConfigList = CodeGeneratorUtil.customFileOutConfig(tableName, moduleName, srcPath, projectPackagePath, resourcesPath);
        cfg.setFileOutConfigList(fileOutConfigList);

        // 策略配置
        StrategyConfig strategy = new StrategyConfig();
        strategy.setNaming(NamingStrategy.underline_to_camel);  //  数据库表映射到实体的命名策略
        strategy.setColumnNaming(NamingStrategy.underline_to_camel);    //  数据库表字段映射到实体的命名策略, 未指定按照 naming 执行
        strategy.setEntityLombokModel(true);    //  【实体】是否为lombok模型（默认 false）
        strategy.setRestControllerStyle(true);//生成 @RestController 控制器
//	     strategy.setInclude(scanner("user,payorder").split(","));
//	     strategy.setInclude(scanner("sys_handcard"));
//        strategy.setInclude(scanner("表名，多个英文逗号分割").split(","));    // 表
        strategy.setInclude(tableName);    // 表
        strategy.setControllerMappingHyphenStyle(true); //  驼峰转连字符
//	     strategy.setTablePrefix(packageConfig.getModuleName() + "_");//表前缀
//        strategy.setTablePrefix(scanner("表前缀"));    //  表前缀
        strategy.setTablePrefix("");    //  表前缀
//        strategy.setLogicDeleteFieldName("is_delete");   //      逻辑删除字段名
//         strategy.setEntityBooleanColumnRemoveIsPrefix(false);    //  去掉布尔值is_前缀
        strategy.setControllerMappingHyphenStyle(true);    //url中驼峰转连字符
        strategy.setTableFillList(Arrays.asList(new TableFill("create_time", FieldFill.INSERT), new TableFill("update_time", FieldFill.INSERT_UPDATE)));  //  自动填充
        strategy.setEntityTableFieldAnnotationEnable(true); //生成@TableName，@TableId，@TableField等注解

        // 配置模板
        TemplateConfig templateConfig = new TemplateConfig();

        // 代码生成器
        AutoGenerator generator = new AutoGenerator();
        generator.setGlobalConfig(globalConfig);    // 全局配置
        generator.setDataSource(dataSource);    //  数据源
        generator.setPackageInfo(packageConfig);    // 包配置
        generator.setCfg(cfg);  // 自定义配置
        generator.setTemplate(templateConfig);  // 配置模板
        generator.setStrategy(strategy);    //  策略配置
        generator.setTemplateEngine(new FreemarkerTemplateEngine());    //  模版引擎
        generator.execute();
    }

    public static void main(String[] args) {

        generator("任建波", "sys_department","system", "com.renjianbo.project");
    }

}
